

// ## 2023/11/11 # 铃 # 目的是为了把后方的作战能力强的武将调度到前线

namespace AI城市优化调度
{

    const int 召唤城市距离 = 1;

    /// =========================================================================================

    // const bool 调试模式 = false;
    // const bool 调试模式2 = false;

    const bool 调试模式 = false;
    const bool 调试模式2 = false;



    const int KEY = pk::hash("AI城市优化调度");

    class Main
    {
        pk::list<pk::person @> actors;
        array<int> base_want_person_for707(据点_末, 0);
        array<int> base_diff_person_for707(据点_末, 0);


        Main()
        {
            pk::bind(202, pk::trigger202_t(onAIRunningOrder));
        }

        void onAIRunningOrder(pk::ai_context @context, pk::building @building, int cmd)
        {
            if (cmd == 据点AI_优化调度)
            {
                pk::force @force = pk::get_force(building.get_force_id());
                pk::ai_context_base @base = context.base[building.get_id()];

             //第一次循环,对所有据点进行赋值(不然寻找据点的时候会存在还未赋值的据点)
                for (int i = 0; i < 据点_末; i++)
                {
                    array<pk::building @> src_base_arr;
                    pk::district @district0 = pk::get_district(pk::get_building(i).get_district_id());

                    base_want_person_for707[i] = ai::base_want_person[i];
                    base_diff_person_for707[i] = ai::base_want_person[i] - ai::base_real_person[i];
                }

            // 如果是玩家城市,就退出
                if (building.is_player())
                    return;

                if(ai::base_statue[building.get_id()] != 据点_后方 and ai::base_statue[building.get_id()] != 据点_警戒)
                return;

                if (调试模式2)
                {
                    pk::trace(pk::format("0{}初期判断,据点状态{}", pk::decode(pk::get_name(building)), ai::base_statue[building.get_id()]));
                }


                array<pk::building @> dst_base_arr = 寻找据点列表(building);

                if (dst_base_arr.length == 0)
                    return;

                if (调试模式2)
                {
                    pk::trace(pk::format("1{}初期判断,据点状态{}", pk::decode(pk::get_name(building)), ai::base_statue[building.get_id()]));
                }

              // 候选据点的优先顺序  所需差距越大 越优先
                dst_base_arr.sort(function(a, b) { return  main.base_diff_person_for707[a.get_id()] > main.base_diff_person_for707[b.get_id()]; });

                pk::building @dst_base = dst_base_arr[0];
                int dst_id = dst_base.get_id();

                auto idle_person_list = pk::get_idle_person_list(pk::get_building(building.get_id()));
                auto person_list = pk::get_person_list(pk::get_building(building.get_id()), pk::mibun_flags(身份_君主, 身份_都督, 身份_太守, 身份_一般));

                //移动人数最大为所有人
                int 移动人数 = person_list.count;
                if (building.get_id() < 城市_末) 移动人数 = pk::min(移动人数, 6);
                if (building.get_id() >= 城市_末) 移动人数 = pk::min(移动人数, 3);

                if (调试模式2)
                {
                    pk::trace(pk::format("2{}初期判断,据点状态{}", pk::decode(pk::get_name(building)), ai::base_statue[building.get_id()]));
                }

                if (移动人数 <= 0) return;

                if (调试模式2)
                {
                    pk::trace(pk::format("3{}初期判断,据点状态{}", pk::decode(pk::get_name(building)), ai::base_statue[building.get_id()]));
                }

                person_list.sort(function(a, b) {
                    return (a.stat[武将能力_统率] * 3 + a.stat[武将能力_武力] + a.stat[武将能力_智力]) > b.stat[武将能力_统率] * 3 + b.stat[武将能力_武力] + b.stat[武将能力_智力];
                });

                pk::list<pk::person @> actors;
                int j = 0;
                for (int i = 0; i < person_list.count; i++)
                {

                    if (pk::is_absent(person_list[i]) or pk::is_unitize(person_list[i]))
                        continue;

                    if (person_list[i].action_done == true)
                        continue;

                    //只调度作战能力比较强的人去前线
                    if (person_list[i].stat[武将能力_统率] < 85 and (person_list[i].stat[武将能力_统率] * 3 + person_list[i].stat[武将能力_武力] + person_list[i].stat[武将能力_智力] < 380))
                        continue;

                    j++;
                    actors.add(person_list[i]);
                    person_list[i].action_done = true;
                    string person_name2 = pk::format("\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(person_list[i])));

                    if (调试模式)
                    {
                        pk::trace(pk::format("{}向{}优化移动了{}", pk::decode(pk::get_name(building)), pk::decode(pk::get_name(dst_base_arr[0])), pk::decode(pk::get_name(person_list[i]))));
                    }
                    if (j >= 移动人数)
                        break;
                }

                // 移动命令
                pk::move_cmd_info cmd_move;
                @cmd_move.base = building;
                @cmd_move.target = dst_base_arr[0];
                cmd_move.actors = actors;
                pk::command(cmd_move);

                ch::remove_idle_person(context, actors);
            }
            return;
        }

            //*********************可调度的候选据点****************

        array<pk::building @> 寻找据点列表(pk::building @building)
        {
            array<pk::building @> dst_base_arr;
            for (int i = 0; i < 据点_末; i++)
            {
                pk::building @dst_base = pk::get_building(i);


                if (!pk::is_alive(dst_base))
                    continue;

                if (dst_base.get_force_id() != building.get_force_id())
                    continue;

                if (i == building.get_id())
                    continue;

                if (调试模式2)
                {
                    pk::trace(pk::format("1{}寻找判断,据点状态{}", pk::decode(pk::get_name(building)), ai::base_statue[i]));
                }

                  //只对前线调度
                if (ai::base_statue[i] == 据点_后方 or ai::base_statue[i] == 据点_警戒)
                    continue;

                  //作战能力不强则不去
                if (i < 城市_末 and pk::get_troops(dst_base) < 30000)
                    continue;

                if (i >= 城市_末 and pk::get_troops(dst_base) < 20000)
                    continue;

                if (pk::get_food(dst_base) < 50000)
                    continue;

                //兵装不足
                if (pk::get_weapon_amount(dst_base, 1) + pk::get_weapon_amount(dst_base, 2) + pk::get_weapon_amount(dst_base, 3) + pk::get_weapon_amount(dst_base, 4) < 20000)
                    continue;


                  //城防不高则不去
                if (dst_base.hp < 5000)
                    continue;

                if (调试模式2)
                {
                    pk::trace(pk::format("2{}寻找判断{}", pk::decode(pk::get_name(building)), pk::decode(pk::get_name(dst_base))));

                    pk::trace(pk::format("3{}寻找判断{},目标所需{},目标真实{}", pk::decode(pk::get_name(building)), pk::decode(pk::get_name(dst_base)), main.base_want_person_for707[i], ai::base_real_person[i]));
                }
                dst_base_arr.insertLast(dst_base);
            }

            return dst_base_arr;
        }

    } Main main;
}